package com.wangsd.web.coupon.controller;


import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wangsd.common.basicbean.Result;
import com.wangsd.common.component.WxjavaService;
import com.wangsd.common.utils.MD5Utils;
import com.wangsd.web.MyController;
import com.wangsd.web.coupon.entity.*;
import com.wangsd.web.coupon.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.wangsd.common.enums.CommonStatic.LOGIN_TOKEN_TYPE_M;
import static com.wangsd.common.enums.ResultCode.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author generator
 * @since 2019-09-10
 */
@Api(value = "wxUser", tags = "微信用户信息")
@RestController
@RequestMapping("/coupon/wxUser")
@Slf4j
public class WxUserController extends MyController {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    MemberService memberService;

    @Autowired
    CompanyService companyService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    WxjavaService wxjavaService;

    @Autowired
    FileManagementService fileManagementService;

    @Autowired
    IntegralDetailService integralDetailService;

    @Autowired
    ConfigService configService;

    @Autowired
    SignDetailService signDetailService;

    @Autowired
    MiniMenuConfigService miniMenuConfigService;

    @Autowired
    BusinessCouponService businessCouponService;

    @Autowired
    ServiceBusinessService serviceBusinessService;

    @Autowired
    TOrderService orderService;

    @Autowired
    MemberCouponService memberCouponService;

    @Autowired
    RedisTemplate redisTemplate;

    @ApiOperation(value = "微信登录", notes = "微信登录", httpMethod = "GET")
    @RequestMapping("/login")
    public Result login(String code) {
        WxMaService service = wxjavaService.getMiniService(getMiniAppid());
        WxMaJscode2SessionResult data = null;
        try {
            data = service.getUserService().getSessionInfo(code);
        } catch (WxErrorException e) {
            log.error("login", e);
        }
        if (data == null) {
            return Result.fail("获取session失败");
        }
        Member member = new Member();
        member.setMiniOpenid(data.getOpenid());
        member.setSessionKey(data.getSessionKey());
        String token = UUID.randomUUID().toString().replace("-", "");
        redisTemplate.opsForValue().set(LOGIN_TOKEN_TYPE_M + token, member, 2, TimeUnit.HOURS);
        Map<String, String> map = new HashMap<>();
        map.put("token", LOGIN_TOKEN_TYPE_M + token);
        return Result.success(map);
    }

    @ApiOperation(value = "授权信息查询", notes = "授权信息查询", httpMethod = "GET")
    @RequestMapping("/isAuth")
    public Result isAuth() {
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String miniOpenid = miniUserInfo.getMiniOpenid();
        String openid = stringRedisTemplate.opsForValue().get(miniOpenid);
        if (openid != null) {
            return Result.success(openid);
        } else {
            return Result.message(MINI_APP_USER_NO_AUTH);
        }
    }

    @ApiOperation(value = "轮询查询购买商家券信息", notes = "轮询查询购买商家券信息", httpMethod = "GET")
    @RequestMapping("/getBuySuccess/{outTradeNo}")
    public Result getBuySuccess(@PathVariable String outTradeNo) {
        String businessCouponId = stringRedisTemplate.opsForValue().get(outTradeNo);
        if (businessCouponId != null) {
            return Result.success(businessCouponId);
        } else {
            return Result.fail("未获取到购买商家券支付回调成功信息");
        }
    }

    @ApiOperation(value = "查询手机号是否保存成功", notes = "查询手机号是否保存成功", httpMethod = "GET")
    @RequestMapping("/isPhone")
    public Result isPhone() {
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String miniOpenid = miniUserInfo.getMiniOpenid();

        Member member = memberService.selectByOpenid(miniOpenid);
        if (member != null && member.getMobile() != null) {
            return Result.success(member);
        } else {
            return Result.message(MINI_APP_USER_NO_PHONE);
        }
    }


    @ApiOperation(value = "获取小程序信息", notes = "获取小程序信息", httpMethod = "GET")
    @RequestMapping("/getAppInfo")
    public Result getAppInfo() {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        return Result.success(company);
    }

    @ApiOperation(value = "保存手机号", notes = "保存手机号", httpMethod = "POST")
    @PostMapping("/savePhone")
    public Result savePhone(String encryptedData, String ivStr) {
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String sessionKey = miniUserInfo.getSessionKey();

        String appid = getMiniAppid();
        WxMaService service = wxjavaService.getMiniService(appid);
        WxMaPhoneNumberInfo info = service.getUserService().getPhoneNoInfo(sessionKey, encryptedData, ivStr);

        Company company = companyService.selectByMiniAppid(appid);

        Member member = new Member();
        member.setMobile(info.getPhoneNumber());
        member.setMiniOpenid(miniUserInfo.getMiniOpenid());
        member.setCompanyId(company.getId());
        member.setState(1);//已认证

        memberService.register(member);
        return Result.success();
    }

    @ApiOperation(value = "查询当前用户信息", notes = "查询当前用户信息", httpMethod = "GET")
    @RequestMapping("/isUserinfo")
    public Result isUserinfo() {
        log.debug("查询当前用户信息isUserinfo");
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String openid = miniUserInfo.getMiniOpenid();

        Member member = memberService.selectByOpenid(openid);
        if (member != null) {
            return Result.success(member);
        } else {
            return Result.message(MINI_APP_USER_NO_INFO);
        }
    }

    @ApiOperation(value = "保存用户信息", notes = "保存用户信息", httpMethod = "POST")
    @PostMapping("/saveUserinfo")
    public Result saveUserinfo(String encryptedData, String ivStr) {

        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String sessionKey = miniUserInfo.getSessionKey();
        String openid = miniUserInfo.getMiniOpenid();

        String appid = getMiniAppid();
        WxMaService service = wxjavaService.getMiniService(appid);
        WxMaUserInfo info = service.getUserService().getUserInfo(sessionKey, encryptedData, ivStr);

        Company company = companyService.selectByMiniAppid(appid);
        if (company == null) {
            return Result.message(MINI_APP_NOT_COMPANY);
        }

        Member member = new Member();
        member.setAvatarUrl(info.getAvatarUrl());
        member.setGender(info.getGender());
        member.setNickName(info.getNickName());
        member.setMiniOpenid(openid);
        member.setCompanyId(company.getId());

        memberService.register(member);
        return Result.success();
    }

    @ApiOperation(value = "查询轮播图片", notes = "查询轮播图片", httpMethod = "GET")
    @GetMapping("/getUploadFile")
    public Result getUploadFile() {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        List<FileManagement> list = fileManagementService.selectByMasterIdAndCompanyId(company.getId(), 1);
        return Result.success(list);
    }

    @ApiOperation(value = "查询总积分", notes = "查询总积分", httpMethod = "POST")
    @PostMapping("/getPointsTotal")
    public Result getPointsTotal() {

        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String openid = miniUserInfo.getMiniOpenid();

        Member member = null;
        try {
            member = memberService.selectByOpenid(openid);
        } catch (Exception e) {
            log.error("getPointsTotal", e);
        }
        return Result.success(member);
    }


    @ApiOperation(value = "添加上级团队", notes = "添加上级团队", httpMethod = "POST")
    @PostMapping("/reset")
    public Result reset(@RequestBody Member params) {
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String openid = miniUserInfo.getMiniOpenid();

        if (params.getMobile() == null) {
            return Result.fail("输入手机号不能为空");
        }
        Company company = companyService.selectByMiniAppid(getMiniAppid());

        /*查询当前手机号对应的member信息*/
        Member parentMember = memberService.selectByCompanyIdAndPhone(params.getMobile(), company.getId());

        if (parentMember == null) {
            return Result.fail("用户不存在！");
        }

        Member currentMember = memberService.selectByOpenid(openid);

        Member member = new Member();
        member.setId(currentMember.getId());
        member.setParentNickName(parentMember.getNickName());
        member.setParentOpenid(parentMember.getMiniOpenid());
        memberService.updateById(member);

        return Result.success();
    }

    @ApiOperation(value = "查询积分明细", notes = "查询积分明细", httpMethod = "GET")
    @GetMapping("/getPointsDetailList/{pageNum}/{pageSize}")
    public Result getPointsDetailList(@PathVariable Integer pageNum,
                                      @PathVariable Integer pageSize) {

        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        String openid = miniUserInfo.getMiniOpenid();
        IPage<IntegralDetail> integralDetailIPage = integralDetailService.selectPage(openid, pageNum, pageSize);
        return Result.success(integralDetailIPage);
    }

    @ApiOperation(value = "通过商圈id查询营销配置", notes = "通过商圈id查询营销配置", httpMethod = "GET")
    @GetMapping("/selectConfigByCompanyId")
    public Result selectConfigByCompanyId() {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        List<Config> configs = configService.selectConfigListByCompanyId(company.getId());
        return Result.success(configs);
    }

    @ApiOperation(value = "通过商圈id查询小程序菜单配置", notes = "通过商圈id查询小程序菜单配置", httpMethod = "GET")
    @GetMapping("/selectMiniMenuConfigByCompanyId")
    public Result selectMiniMenuConfigByCompanyId() {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        List<MiniMenuConfig> miniMenuConfigs = miniMenuConfigService.selectConfigListByCompanyId(company.getId());
        return Result.success(miniMenuConfigs);
    }

    @ApiOperation(value = "通过openid获取到当前会员签到", notes = "通过openid获取到当前会员签到", httpMethod = "GET")
    @GetMapping("/sign")
    @ResponseBody
    public Result sign() {
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        try {
            Integer sign = signDetailService.sign(miniUserInfo.getMiniOpenid());
            if (-1 == sign) {
                return Result.fail("今天已经签到了！！");
            }
            if (-2 == sign) {
                return Result.fail("请先在pc端设置签到积分默认值！！");
            }
            return Result.success(sign);
        } catch (Exception e) {
            log.error("sign", e);
        }
        return Result.fail("通过openid获取到当前会员签到！！");
    }


    /**
     * 通过openid获取到当前会员签到的详情列表
     *
     * @return
     */
    @ApiOperation(value = "通过获取到当前会员签到的详情列表", notes = "通过openid获取到当前会员签到的详情列表", httpMethod = "GET")
    @GetMapping("/selectListByOpenid")
    public Result selectListByOpenid() {
        Member miniUserInfo = getMiniUserInfo();
        if (miniUserInfo == null) {
            return new Result(NO_LOGIN);
        }
        try {
            List<SignDetail> signDetails = signDetailService.selectListByOpenid(miniUserInfo.getMiniOpenid());
            return Result.success(signDetails);
        } catch (Exception e) {
            log.error("selectListByOpenid", e);
        }
        return Result.fail("通过openid获取到当前会员签到的详情列表！！");
    }


    /**
     * 查询当前小程序下的类别
     *
     * @return
     */
    @ApiOperation(value = "查询当前小程序下的类别", notes = "查询当前小程序下的类别", httpMethod = "GET")
    @GetMapping("/selectListCategory")
    public Result selectListCategory() {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        try {
            List<Category> list = categoryService.list(new QueryWrapper<Category>().eq("company_id", company.getId()));
            return Result.success(list);
        } catch (Exception e) {
            log.error("selectListCategory", e);
        }
        return Result.fail("查询当前小程序下的类别！！");
    }

    /**
     * 查询当前小程序下的商家券验签
     *
     * @return
     */
    @ApiOperation(value = "查询当前小程序下的商家券验签", notes = "查询当前小程序下的商家券验签", httpMethod = "GET")
    @GetMapping("/doSign/{id}")
    public Result doSign(@PathVariable String id) {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        try {
            ServiceBusiness serviceBusiness = serviceBusinessService.getById(company.getBusinessServiceId());
            BusinessCoupon businessCoupon = businessCouponService.getById(id);
            String belongMerchant = businessCoupon.getBelongMerchant();
//            String outRequestNo = businessCoupon.getOutRequestNo();
            String outRequestNo = belongMerchant+""+System.currentTimeMillis();
            String stockId = businessCoupon.getStockId();
            SortedMap<String, String> map = new TreeMap();
            map.put("out_request_no0", outRequestNo);
            map.put("send_coupon_merchant", serviceBusiness.getMchId());
            map.put("stock_id0", stockId);
            String sha256Sign = MD5Utils.getSHA256SignPlus(map, serviceBusiness.getMchKey(), 2);
            Map<String, Object> resultMap = new HashMap<>();
            JSONArray paramsArray = new JSONArray();
            JSONObject paramObject = new JSONObject();
            paramObject.put("stock_id", stockId);
            paramObject.put("out_request_no", outRequestNo);
            paramsArray.add(paramObject);
            resultMap.put("send_coupon_params", paramsArray);
            resultMap.put("sign", sha256Sign);
            resultMap.put("send_coupon_merchant", serviceBusiness.getMchId());
            return Result.success(resultMap);
        } catch (Exception e) {
            log.error("doSign", e);
        }
        return Result.fail("查询当前小程序下的商家券验签！！");
    }

    /**
     * 保存商家券信息到会员表中
     *
     * @return
     */
    @ApiOperation(value = "保存商家券信息到会员表中", notes = "保存商家券信息到会员表中", httpMethod = "POST")
    @PostMapping("/saveMemberCoupon")
    public Result saveMemberCoupon(@RequestBody MemberCoupon memberCoupon) {
        Company company = companyService.selectByMiniAppid(getMiniAppid());
        if (memberCoupon == null) {
            return Result.fail("参数错误");
        }
        if (StringUtils.isBlank(memberCoupon.getOutTradeNo())) {
            return Result.fail("商户单号不能为空");
        }
        if (StringUtils.isBlank(memberCoupon.getCouponCode())) {
            return Result.fail("商家券码不能为空");
        }
        if (StringUtils.isBlank(memberCoupon.getStockId())) {
            return Result.fail("商家券批次号不能为空");
        }
        TOrder order = orderService.selectByOutTradeNo(memberCoupon.getOutTradeNo());
        if (order == null) {
            return Result.fail("订单不存在");
        }
        Member member = memberService.selectByOpenid(order.getOpenid());
        try {
            MemberCoupon params = new MemberCoupon();
            params.setType(2);
            params.setState(0);
            params.setOpenid(order.getOpenid());
            params.setPayOpenid(member.getPayOpenid());
            params.setMemberId(member.getId());
            params.setStockId(memberCoupon.getStockId());
            params.setCouponCode(memberCoupon.getCouponCode());
            params.setOutTradeNo(memberCoupon.getOutTradeNo());
            memberCouponService.save(params);
            /*修改该订单为未领取*/
            TOrder newOrder = new TOrder();
            newOrder.setId(order.getId());
            newOrder.setSendType(1);
            orderService.updateById(newOrder);
            return Result.success();
        } catch (Exception e) {
            log.error("saveMemberCoupon", e);
        }
        return Result.fail("保存商家券信息到会员表中");
    }
}